Custom widgets are a special subset of scripts that render graphical elements in certain parts of the application. These can be used to add new functionality to the Trilium application.
In older versions of Trilium, custom widgets were exclusively written
in a combination of jQuery with Trilium's internal widget architecture
(e.g., BasicWidget, NoteContextAwareWidget).
Starting with v0.101.0, custom widgets can also be written in JSX using the Preact framework. Both legacy and Preact widgets have the same capabilities, with a single difference:
this.contentSized() applied
in the constructor. For more information, see the corresponding section
in Troubleshooting.Wherever possible, widget examples will be both in the legacy and Preact format.
The quickest way is Insert child note → Code → Widget in
the Note tree contextual menu.
It creates a JSX note with the #widget label and a minimal Preact
widget to start from.
To set one up by hand instead:
#widget label.Let's start by creating a widget that shows a message near the content area. Follow the previous section to create a code note, and use the following content.
Preact
import { defineWidget } from "trilium:preact";
export default defineWidget({
parent: "center-pane",
render: () => <span>Center pane from Preact.</span>
});
Legacy
class HelloCenterPane extends api.BasicWidget {
constructor() {
super();
this.contentSized();
}
get parentWidget() { return "center-pane" }
doRender() {
this.$widget = $("<span>Center pane</span>");
}
}
module.exports = new HelloCenterPane();
Refresh the application and the widget should appear underneath the content area.
A widget can be placed in one of the following sections of the applications:
Value for parentWidget
|
Description | Sample widget | Special requirements |
|---|---|---|---|
left-pane
|
Appears within the same pane that holds the Note Tree. | Same as above, with only a different parentWidget. |
None. |
center-pane
|
In the content area. If a split is open, the widget will span all of the splits. | See example above. | None. |
note-detail-pane
|
In the content area, inside the note detail area. If a split is open, the widget will be contained inside the split. This is ideal if the widget is note-specific. |
Note context aware widget |
|
right-pane
|
In the Right Sidebar, as a dedicated section. | Right pane widget |
|
To position the widget somewhere else, just change the value passed to get parentWidget() for
legacy widgets or the parent field for Preact. Do note that
some positions such as note-detail-pane and right-pane have
special requirements that need to be accounted for (see the table above).
A widget note usually returns one widget, but it can also return an array of them. This is useful when several widgets share code or state, since they can all live in the same note instead of being split across notes that need a shared module.
Each widget of the array is registered on its own, so they can have different
parents and positions. A widget that is missing its parentWidget (or parent for
Preact) is reported as an error without affecting the other widgets of
the note.
Preact
import { defineWidget } from "trilium:preact";
export default [
defineWidget({
parent: "left-pane",
render: () => <span>Left pane from Preact.</span>
}),
defineWidget({
parent: "right-pane",
render: () => <span>Right pane from Preact.</span>
})
];
Legacy
class TreeWidget extends api.BasicWidget {
get parentWidget() { return "left-pane"; }
doRender() { this.$widget = $("<span>Left pane</span>"); }
}
class SidebarWidget extends api.BasicWidget {
get parentWidget() { return "right-pane"; }
doRender() { this.$widget = $("<span>Right pane</span>"); }
}
module.exports = [ new TreeWidget(), new SidebarWidget() ];
Launch bar widgets are similar to Custom widgets but are specific to the Launch Bar. See Launch Bar Widgets for more information.
The position of a custom widget is defined via a position integer.
Preact
export default defineWidget({
// [...]
position: 10
});
Legacy
class MyWidget extends api.BasicWidget {
// [..
get position() { return 10; }
}